/*
Authors: Eli Yucht 300388949 and Lior Fass 300069705
Project: SCP (Switch Schedule Policy)
Description: Scheduler class
*/


#ifndef SCHEDULER_H
#define SCHEDULER_H


#include "Flow.h"


#define MAX_LINE_BUF 256

/* Input line is a struct that contain all the information from a single input line:
	Packet pkt - the packet information from the line
				(contain pktID, arriving_time and length)

	char* sadd, *dadd - source and destination ip address
	unsigned short int sport, dport - source and destination port
	unsigned short int [weight]  - [optional] the weight of the flow (for WRR/DRR)
	
*/
struct Input_line
{
	Packet pkt;
	char* sadd, *dadd;
	unsigned short int sport, dport;
	unsigned short int weight;
};


/*	Scheduler class declaration
	Notice that Scheduler is Abstract base classes 

	the scheduler class contain the following members:

	FILE* infile_p - the input file pointer
	FILE* outfile_p - the output file pointer
	int quantum - quantum (for DRR)
	char line_buf[MAX_LINE_BUF] - a temp input string from the input file

	long int current_time - the current time of the scheduler
	unsigned short int num_of_flows - the total number of flows in the system
	unsigned short int counter_of_empty_flows - counter of how many flows are empty in a row

	Flow* head_flow_queue - a pointer to the head of the flows queue
	Flow* tail_flow_queue - a pointer to the tail (end) of the flows queue
	Flow* current_flow - a pointer to the current schedule flow

	Input_line nextPacket - the next packet from the input file

	bool need_to_load_next_time - indicate if we need to load the 
								last packet that was read from the input file
	bool empty_queues - indicate if all the flows are empty and so we need to promote the current time
	bool end_of_input - indicate if we reach the end of the input file

	*/
class Scheduler
{
public:
	Scheduler();
	int Initialize_Scheduler(int inQuantum, char* infile_name, char* outfile_name);
	int RunScheduler();
	~Scheduler();

protected:
	virtual int HandleAllEmpty();
	virtual void HandleCurrentFlowEmpty();
	virtual int ScheduleCurrentFlow() = 0; // pure virtual method

	FILE* outfile_p;
	int quantum;

	long int current_time;
	unsigned short int num_of_flows;
	unsigned short int counter_of_empty_flows;

	Flow* head_flow_queue;
	Flow* tail_flow_queue;
	Flow* current_flow;

	bool empty_queues;
	bool end_of_input;

	int Load_data_to_Schedule();
	void Go_to_Next_Flow();
	
private:
	FILE* infile_p;
	
	char line_buf[MAX_LINE_BUF];
	Input_line nextPacket;

	bool need_to_load_next_time;

	Flow* Find_Flow();
	int Get_Pkt_From_File(bool first_time);
	int Load_Flow();

};

#endif // SCHEDULER_H